package com.firefly.admin.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.firefly.admin.common.constant.Constants;
import com.firefly.admin.common.enums.ResultCodeEnum;
import com.firefly.admin.common.enums.WhiteListTypeEnum;
import com.firefly.admin.common.utils.RedisUtil;
import com.firefly.admin.common.vo.Result;
import com.firefly.admin.monitor.vo.SelectResult;
import com.firefly.admin.system.entity.FySystemWhiteList;
import com.firefly.admin.system.mapper.FySystemWhiteListMapper;
import com.firefly.admin.system.service.FySystemRoleService;
import com.firefly.admin.system.service.FySystemUserService;
import com.firefly.admin.system.service.FySystemWhiteListService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.firefly.admin.system.entity.FySystemRole;
import com.firefly.admin.system.entity.FySystemUser;
import com.firefly.admin.system.vo.SystemWhiteListQueryVo;
import com.firefly.admin.system.vo.SystemWhiteListStatusUpdateVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class FySystemWhiteListServiceImpl implements FySystemWhiteListService {
    @Autowired
    private FySystemWhiteListMapper fySystemWhiteListMapper;
    @Autowired
    private FySystemUserService fySystemUserService;
    @Autowired
    private FySystemRoleService fySystemRoleService;

    /**
     * 分页查询系统白名单接口
     *
     * @param systemWhiteListQueryVo 分页查询参数
     * @return 分页列表
     */
    @Override
    public Result<Page<FySystemWhiteList>> getSystemWhiteListPage(SystemWhiteListQueryVo systemWhiteListQueryVo) {
        log.info("###########FySystemWhiteListServiceImpl getSystemWhiteListPage param = {}", JSONObject.toJSONString(systemWhiteListQueryVo));
        LambdaQueryWrapper<FySystemWhiteList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(systemWhiteListQueryVo.getWhiteListType()), FySystemWhiteList::getWhiteListType, systemWhiteListQueryVo.getWhiteListType());
        queryWrapper.eq(FySystemWhiteList::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        queryWrapper.orderByDesc(FySystemWhiteList::getCreateTime);
        Page<FySystemWhiteList> page = new Page<>(systemWhiteListQueryVo.getPage(), systemWhiteListQueryVo.getLimit());
        Page<FySystemWhiteList> listPage = fySystemWhiteListMapper.selectPage(page, queryWrapper);
        return Result.success(listPage);
    }

    /**
     * 系统白名单信息新增接口
     *
     * @param fySystemWhiteList 系统白名单信息
     * @return 新增结果
     */
    @Override
    public Result<FySystemWhiteList> add(FySystemWhiteList fySystemWhiteList) {
        if (fySystemWhiteList == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        ResultCodeEnum resultCodeEnum = checkWhiteListParam(fySystemWhiteList);
        if (resultCodeEnum != null) {
            return Result.getResult(resultCodeEnum);
        }
        int rows = fySystemWhiteListMapper.insert(fySystemWhiteList);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.ADD_EXCEPTION);
        }
        refreshWhiteListCache(fySystemWhiteList.getWhiteListId());
        return Result.success(fySystemWhiteList);
    }

    /**
     * 系统白名单信息编辑接口
     *
     * @param fySystemWhiteList 系统白名单信息
     * @return 编辑结果
     */
    @Override
    public Result<FySystemWhiteList> update(FySystemWhiteList fySystemWhiteList) {
        if (fySystemWhiteList == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        Long whiteListId = fySystemWhiteList.getWhiteListId();
        if (whiteListId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        ResultCodeEnum resultCodeEnum = checkWhiteListParam(fySystemWhiteList);
        if (resultCodeEnum != null) {
            return Result.getResult(resultCodeEnum);
        }
        int rows = fySystemWhiteListMapper.updateById(fySystemWhiteList);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.UPDATE_EXCEPTION);
        }
        refreshWhiteListCache(whiteListId);
        return Result.success(fySystemWhiteList);
    }

    private ResultCodeEnum checkWhiteListParam(FySystemWhiteList fySystemWhiteList) {
        Long whiteListId = fySystemWhiteList.getWhiteListId();
        if (whiteListId != null) {
            FySystemWhiteList systemWhiteList = fySystemWhiteListMapper.selectById(whiteListId);
            if (systemWhiteList == null) {
                return ResultCodeEnum.SYSTEM_WHITE_LIST_NOT_FOUND;
            }
        }
        if (StringUtils.isBlank(fySystemWhiteList.getWhiteListType())) {
            return ResultCodeEnum.SYSTEM_WHITE_LIST_TYPE_NOT_NULL;
        }
        if (StringUtils.isBlank(fySystemWhiteList.getWhiteListValue())) {
            return ResultCodeEnum.SYSTEM_WHITE_LIST_VALUE_NOT_NULL;
        }
        String whiteListStatus = fySystemWhiteList.getWhiteListStatus();
        if (whiteListId == null && StringUtils.isBlank(whiteListStatus)) {
            fySystemWhiteList.setWhiteListStatus(Constants.Status.ENABLE);
        }
        return null;
    }

    /**
     * 系统白名单状态修改接口
     *
     * @param systemWhiteListStatusUpdateVo 系统白名单状态编辑参数
     * @return 操作结果
     */
    @Override
    public Result<String> updateStatus(SystemWhiteListStatusUpdateVo systemWhiteListStatusUpdateVo) {
        if (systemWhiteListStatusUpdateVo == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        Long whiteListId = systemWhiteListStatusUpdateVo.getWhiteListId();
        if (whiteListId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        FySystemWhiteList fySystemWhiteList = fySystemWhiteListMapper.selectById(whiteListId);
        if (fySystemWhiteList == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_WHITE_LIST_NOT_FOUND);
        }
        String whiteListStatus = systemWhiteListStatusUpdateVo.getWhiteListStatus();
        if (StringUtils.isBlank(whiteListStatus)) {
            return Result.getResult(ResultCodeEnum.SYSTEM_WHITE_LIST_STATUS_NOT_NULL);
        }
        fySystemWhiteList.setWhiteListStatus(whiteListStatus);
        int rows = fySystemWhiteListMapper.updateById(fySystemWhiteList);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.UPDATE_EXCEPTION);
        }
        refreshWhiteListCache(whiteListId);
        return Result.success();
    }

    /**
     * 系统白名单信息删除接口
     *
     * @param whiteListId 白名单ID
     * @return 删除结果
     */
    @Override
    public Result<String> delete(Long whiteListId) {
        if (whiteListId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        FySystemWhiteList fySystemWhiteList = fySystemWhiteListMapper.selectById(whiteListId);
        if (fySystemWhiteList == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_WHITE_LIST_NOT_FOUND);
        }
        fySystemWhiteList.setDeleteFlag(Constants.DeleteFlag.DELETE);
        String whiteListType = fySystemWhiteList.getWhiteListType();
        int rows = fySystemWhiteListMapper.updateById(fySystemWhiteList);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.DELETE_EXCEPTION);
        }
        RedisUtil.hdel(Constants.Redis.WHITE_LIST_KEY, whiteListType);
        return Result.success();
    }

    /**
     * 白名单类型枚举列表查询接口
     *
     * @return 白名单类型列表
     */
    @Override
    public Result<List<SelectResult>> getWhiteListTypeEnumList() {
        WhiteListTypeEnum[] whiteListTypeEnums = WhiteListTypeEnum.values();
        List<SelectResult> whiteListTypeList = new ArrayList<>();
        for (WhiteListTypeEnum whiteListTypeEnum : whiteListTypeEnums) {
            SelectResult selectResult = new SelectResult();
            selectResult.setName(whiteListTypeEnum.getWhiteListName());
            selectResult.setValue(whiteListTypeEnum.getWhiteListType());
            whiteListTypeList.add(selectResult);
        }
        return Result.success(whiteListTypeList);
    }

    /**
     * 获取所有可用白名单
     *
     * @return 白名单列表
     */
    @Override
    public List<FySystemWhiteList> getAllWhiteList() {
        LambdaQueryWrapper<FySystemWhiteList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemWhiteList::getWhiteListStatus, Constants.Status.ENABLE);
        queryWrapper.eq(FySystemWhiteList::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        return fySystemWhiteListMapper.selectList(queryWrapper);
    }

    /**
     * 获取敏感数据白名单可选用户和角色接口
     *
     * @return 可选用户和角色
     */
    @Override
    public Result<Map<String, List<SelectResult>>> getSensitiveDataList() {
        List<FySystemUser> systemUserList = fySystemUserService.getAllUsableUser();
        Map<String, List<SelectResult>> resultMap = new HashMap<>();
        List<SelectResult> userList = new ArrayList<>();
        systemUserList.forEach(fySystemRole -> {
            SelectResult selectResult = new SelectResult();
            selectResult.setName(fySystemRole.getUserName());
            selectResult.setValue(fySystemRole.getUserId() + "");
            userList.add(selectResult);
        });
        List<FySystemRole> systemRoleList = fySystemRoleService.getAllUsableRoleList().getData();
        List<SelectResult> roleList = new ArrayList<>();
        systemRoleList.forEach(fySystemRole -> {
            SelectResult selectResult = new SelectResult();
            selectResult.setName(fySystemRole.getRoleName());
            selectResult.setValue(fySystemRole.getRoleId() + "");
            roleList.add(selectResult);
        });
        resultMap.put("userList", userList);
        resultMap.put("roleList", roleList);
        return Result.success(resultMap);
    }

    /**
     * 通过白名单类型获取白名单列表
     *
     * @param whiteListType 白名单类型
     * @return 白名单列表
     */
    @Override
    public List<FySystemWhiteList> getValueList(String whiteListType) {
        LambdaQueryWrapper<FySystemWhiteList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemWhiteList::getWhiteListType, whiteListType);
        queryWrapper.eq(FySystemWhiteList::getWhiteListStatus, Constants.Status.ENABLE);
        queryWrapper.eq(FySystemWhiteList::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        return fySystemWhiteListMapper.selectList(queryWrapper);
    }

    /**
     * 刷新redis
     *
     * @param whiteListId 白名单ID
     */
    @Override
    public void refreshWhiteListCache(Long whiteListId) {
        //刷新redis
        FySystemWhiteList fySystemWhiteList = fySystemWhiteListMapper.selectById(whiteListId);
        LambdaQueryWrapper<FySystemWhiteList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemWhiteList::getWhiteListType, fySystemWhiteList.getWhiteListType());
        queryWrapper.eq(FySystemWhiteList::getWhiteListStatus, Constants.Status.ENABLE);
        queryWrapper.eq(FySystemWhiteList::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemWhiteList> whiteLists = fySystemWhiteListMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(whiteLists)) {
            RedisUtil.hdel(Constants.Redis.WHITE_LIST_KEY, fySystemWhiteList.getWhiteListType());
        } else {
            RedisUtil.hset(Constants.Redis.WHITE_LIST_KEY, fySystemWhiteList.getWhiteListType(), whiteLists);
        }
    }

    /**
     * 查询所有正常状态的白名单
     *
     * @return 正常状态白名单列表
     */
    @Override
    public List<FySystemWhiteList> findAllNormal() {
        LambdaQueryWrapper<FySystemWhiteList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemWhiteList::getWhiteListStatus, Constants.Status.ENABLE);
        queryWrapper.eq(FySystemWhiteList::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        return fySystemWhiteListMapper.selectList(queryWrapper);
    }

}
